/*!
 Temelia - Graph structure frontend. It contains function declarations used
 by various backend implementations.

 For example GRAPH_FRONTEND(matrix) generates the prototypes for graph
 implemented with adjacency matrix. Similar, GRAPH_FRONTEND(list) generates
 prototypes for graph implemented with linked lists.

 The basic idea is to avoid code duplication when functions respect a standard
 declaration convention.

 It's not used any more because of compilation problems (MACRO preprocessor
 works in a single stage).

 Copyright (C) 2008, 2009 Ceata (http://ceata.org/proiecte/temelia)

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef GRAPH_FRONTEND_H_
#define GRAPH_FRONTEND_H_

#include "platform.h"
#include "vertex.h"
#include "edge.h"

#define GRAPH_FRONTEND(TYPE)\
/*!
 * @brief Singleton containing structure filled with corresponding
 * pointers to functions.
 */\
DECLSPEC graph_implementation_t graph_##TYPE_get_implementation();\
\
/*!
 * @brief Returns new empty graph represented with adjacency matrix.
 * @param Number of vertices
 */\
DECLSPEC void *graph_##TYPE_new(int size);\
\
/*!
 * @brief Frees the memory occupied by this graph representation.
 * @param Graph representation reference
 */\
DECLSPEC void graph_##TYPE_delete(void *graph);\
\
/*!
 * @brief Resizes current graph representation to new size.
 * @param Graph representation reference
 * @param New size - should be greater than current size
 */\
DECLSPEC void graph_##TYPE_resize(void *graph, int size);\
\
/*!
 * @brief Adds new edge to adjacency matrix; edge is identified
 * by vertices and attributes.
 * @param Graph representation reference
 * @param Edge
 */\
DECLSPEC void graph_##TYPE_add_edge(void *graph, unsigned int src, unsigned int dest,\
		edge_t edge);\
\
/*!
 * @brief Removes an edge identified by vertices and returns
 * the reference.
 * @param Graph representation reference
 * @param Vertex 1
 * @param Vertex 2
 * @return Edge between vertex 1 and vertex 2
 */\
DECLSPEC edge_t graph_##TYPE_remove_edge(void *graph, unsigned int vertex1,\
		unsigned int vertex2);\
\
/*
 * @see graph_##TYPE_remove_edge
 */\
DECLSPEC edge_t graph_##TYPE_get_edge(void *graph, unsigned int vertex1,\
		unsigned int vertex2);\
\
/*!
 * @brief Returns the first neighbor vertex of given vertex.
 * Context is set up because of the iteration property.
 * @param Graph representation reference
 * @param Vertex
 * @param Context reference, where iteration information is stored.
 * In this implementation, you must pass a valid (unsigned int *)
 */\
DECLSPEC vertex_t graph_##TYPE_first_vertex(void *graph, unsigned int vertex,\
		void **context);\
\
/*!
 * @brief Deletes allocated context for iterating, by graph_##TYPE_first_vertex.
 * Notice that it is automatically called when the iterating process is over
 *
 * @param Context
 */\
DECLSPEC void graph_##TYPE_delete_vertex_context(void **context);\
\
/*!
 * @brief Returns the next neighbor vertex of given vertex.
 * Context is used to find out the last visited neighbor.
 * @param Graph representation reference
 * @param Vertex
 * @param Context reference, where iteration information is stored.
 */\
DECLSPEC vertex_t graph_##TYPE_next_vertex(void *graph, unsigned int vertex,\
		void **context);\
\
/*!
 * @brief Returns the first edge with a neighbor vertex of given vertex.
 * Context is set up because of the iteration property.
 * @param Graph representation reference
 * @param Vertex
 * @param Context reference, where iteration information is stored.
 * In this implementation, you must pass a valid (unsigned int *)
 */\
DECLSPEC edge_t graph_##TYPE_first_edge(void *graph, unsigned int vertex, void **context);\
\
/*!
 * @brief Deletes allocated context for iterating, by graph_##TYPE_first_edge.
 * Notice that it is automatically called when the iterating process is over
 * @param Context
 */\
DECLSPEC void graph_##TYPE_delete_edge_context(void **context);\
\
/*!
 * @brief Returns the edge to the next neighbor.
 * Context is used to find out the last visited edge.
 * @param Graph representation reference
 * @param Vertex
 * @param Context reference, where iteration information is stored.
 */\
DECLSPEC edge_t graph_##TYPE_next_edge(void *graph, unsigned int vertex,\
		void **context);\
\
/*!
 * @brief Iterates over the edges of current graph and calls
 * the callback function for-each record.
 * If you want to pretty debug the graph, then see the examples
 * in temelia_samples. Basically, it uses a static variable to
 * count current edge id and when id is equal to the number of vertices
 * it emits a newline and resets id to 0.
 *
 * @param Graph
 * @param Iterating callback function
 */\
DECLSPEC void graph_##TYPE_iterate(void *graph, void(*iterate)(vertex_t src,\
		vertex_t dest, double cost, int *label, void *key, int TYPE));\
\
/*!
 * @brief Iterates over the edge of graph.
 * Complexity O(V*V)
 *
 * @see graph_##TYPE_iterate
 */\
DECLSPEC void graph_##TYPE_iterate_edges(void *graph, void edge_handler(edge_t e,\
		void *context), void *context);\
\
/*!
 * @brief Transposes graph
 * @param Graph
 */\
DECLSPEC void graph_##TYPE_transpose(void *graph);\
\
/*!
 * @brief Computes degree, in degree and out degree of graph
 * @param Graph
 * @param Vertex identifier
 */\
DECLSPEC unsigned int graph_##TYPE_vertex_degree(void *graph, unsigned int vertex);\
DECLSPEC unsigned int graph_##TYPE_vertex_in_degree(void *graph, unsigned int vertex);\
DECLSPEC unsigned int graph_##TYPE_vertex_out_degree(void *graph, unsigned int vertex);\
\
/*!
 * @brief Computes graph's dimension - number of edges
 * @param Graph
 */\
DECLSPEC unsigned int graph_##TYPE_dimension(void *graph);\
\
/*!
 * @brief Removes and deletes the edges from/in vertex
 * @param Graph
 * @param Vertex identifier
 * @param Edge destructor
 */\
DECLSPEC void graph_##TYPE_delete_vertex_edges(void *graph, unsigned int vertex,\
		void(*edge_delete)(edge_t edge));\

#endif /* GRAPH_FRONTEND_H_ */
